
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;

namespace cmd
{
    /// <summary>
    /// 关卡管理员
    /// </summary>
    /// <example>
    /// LevelDataManager.Instance.LevelDatas // 取得包含所有关卡的字典，关卡Id为键
    /// <br/>
    /// level.GetPickableItemsInLayer(layer) // 取得关卡目标层所有生成的物品
    /// </example>
    [DisallowMultipleComponent]
    public sealed class LevelDataManager : SerializedMonoBehaviour
    {
        #region 常量
        public const string LEVEL_MODELS_PATH = "Levels";
        public const string LEVEL_LAYER_MODELS_PATH = "LevelLayers";
        #endregion

        #region 单例
        [field: SerializeField, Required]
        public LevelDataManager Instance { get; private set; }
        #endregion

        #region 数据
        private Dictionary<uint, LevelDataModelSO> _levelDatas = new();

        /// <summary>包含了所有关卡数据的字典</summary>
        public IReadOnlyDictionary<uint, LevelDataModelSO> LevelDatas => _levelDatas;
        #endregion

        #region 统计
        [field: ShowInInspector, ReadOnly, Space(20)]
        public static int LevelDatasCount { get; set; } = 0;

        [field: ShowInInspector, ReadOnly]
        public static uint MaxLevelDataId { get; set; } = 0;

        [field: ShowInInspector, ReadOnly, Space(20)]
        public static int LevelLayerDatasCount { get; set; } = 0;

        // [field: ShowInInspector, ReadOnly]
        // public static uint MaxLevelLayerDataId { get; set; } = 0;
        #endregion

        #region 工具方法
        /// <summary>
        /// 从Resources文件夹加载所有关卡模型SO
        /// </summary>
        [Button, PropertySpace(10)]
        public static LevelDataModelSO[] LoadLevelDataModelSOs()
        {
            // 加载Resources/LevelModels文件夹下的所有SO文件
            LevelDataModelSO[] levelModelSOs = Resources.LoadAll<LevelDataModelSO>(
                LEVEL_MODELS_PATH
            );

            LevelDatasCount = levelModelSOs.Length;
            MaxLevelDataId = levelModelSOs.Max(x => x.Id);

            return levelModelSOs;
        }

        /// <summary>
        /// 从Resources文件夹加载所有关卡层模型SO
        /// </summary>
        [Button, PropertySpace(10)]
        public static LevelLayerDataSO[] LoadLevelLayerDataSOs()
        {
            // 加载Resources/LevelLayerModels文件夹下的所有SO文件
            LevelLayerDataSO[] levelLayerModelSOs = Resources.LoadAll<LevelLayerDataSO>(
                LEVEL_LAYER_MODELS_PATH
            );

            LevelLayerDatasCount = levelLayerModelSOs.Length;
            // MaxLevelLayerDataId = levelLayerModelSOs.Max(x => x.Id);

            return levelLayerModelSOs;
        }

        /// <summary>
        /// 检查关卡Id是否有重复
        /// </summary>
        /// <param name="logIfNoDuplicate">当没有重复时是否打印信息</param>
        public static void CheckDuplicateLevelIds(bool logIfNoDuplicate = true)
        {
            LevelDataModelSO[] levelModelSOs = LoadLevelDataModelSOs();

            var duplicateIds = levelModelSOs
                .GroupBy(x => x.Id)
                .Where(g => g.Count() > 1)
                .Select(g => g.Key);

            if (!duplicateIds.Any())
            {
                if (logIfNoDuplicate)
                    Debug.Log("没有发现关卡存在重复Id");
                return;
            }

            // 如果有重复的Id，输出警告
            foreach (var id in duplicateIds)
            {
                var duplicates = levelModelSOs.Where(x => x.Id == id);
                Debug.LogWarning($"发现重复的关卡Id: {id}");
                foreach (var duplicate in duplicates)
                {
                    Debug.LogWarning($"- {id}  {duplicate.name}");
                }
            }
        }

        /// <summary>
        /// 检查关卡Id是否有重复
        /// </summary>
        [Button(ButtonSizes.Medium), PropertySpace(10)]
        public static void CheckDuplicateLevelIds() => CheckDuplicateLevelIds(true);

        /// <summary>
        /// 检查关卡层Id是否有重复
        /// </summary>
        /// <param name="logIfNoDuplicate">当没有重复时是否打印信息</param>
        public static void CheckDuplicateLevelLayerIds(bool logIfNoDuplicate = true)
        {
            LevelLayerDataSO[] levelLayerModelSOs = LoadLevelLayerDataSOs();

            var duplicateIds = levelLayerModelSOs
                .GroupBy(x => x.Id)
                .Where(g => g.Count() > 1)
                .Select(g => g.Key);

            if (!duplicateIds.Any())
            {
                if (logIfNoDuplicate)
                    Debug.Log("没有发现关卡层存在重复Id");
                return;
            }

            // 如果有重复的Id，输出警告
            foreach (var id in duplicateIds)
            {
                var duplicates = levelLayerModelSOs.Where(x => x.Id == id);
                Debug.LogWarning($"发现重复的关卡层Id: {id}");
                foreach (var duplicate in duplicates)
                {
                    Debug.LogWarning($"- {id}  {duplicate.name}");
                }
            }
        }

        /// <summary>
        /// 检查关卡层Id是否有重复
        /// </summary>
        [Button(ButtonSizes.Medium), PropertySpace(10)]
        public static void CheckDuplicateLevelLayerIds() => CheckDuplicateLevelLayerIds(true);
        #endregion

        void Start()
        {
            // 读取并初始化关卡数据字典
            var levelDataSOs = LoadLevelDataModelSOs();
            _levelDatas ??= new();
            foreach (var levelDataSO in levelDataSOs)
            {
                if (!_levelDatas.ContainsKey(levelDataSO.Id))
                {
                    _levelDatas.Add(levelDataSO.Id, levelDataSO);
                }
                else
                {
                    Debug.LogWarning($"关卡数据字典中已存在Id为{levelDataSO.Id}的关卡数据，执行查重方法");
                }
            }
        }
    }
}
